package com.ruoyi.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.app.domain.AppAddressBook;
import com.ruoyi.app.domain.AppFriend;
import com.ruoyi.app.domain.AppLikeSign;
import com.ruoyi.app.domain.bo.AppFriendBo;
import com.ruoyi.app.domain.bo.AppLikeNotesBo;
import com.ruoyi.app.domain.bo.AppLikeNumberBo;
import com.ruoyi.app.domain.bo.AppLikeSignBo;
import com.ruoyi.app.domain.vo.AppAddressBookVo;
import com.ruoyi.app.domain.vo.AppFriendVo;
import com.ruoyi.app.domain.vo.AppLikeNotesVo;
import com.ruoyi.app.domain.vo.UserVo;
import com.ruoyi.app.mapper.AppAddressBookMapper;
import com.ruoyi.app.mapper.AppFriendMapper;
import com.ruoyi.app.service.*;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.LikeStatus;
import com.ruoyi.common.enums.TableNumberType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * APP用户关注Service业务层处理
 *
 * @author heike
 * @date 2023-01-04
 */
@RequiredArgsConstructor
@Service
public class AppFriendServiceImpl implements IAppFriendService {

    private final AppFriendMapper baseMapper;
    private final IAppUserService appUserService;
    private final IAppDynamicVideoService appDynamicVideoService;
    private final AppAddressBookMapper appAddressBookMapper;
    private final IAppAddressBookService appAddressBookService;
    private final IAppLikeNotesService appLikeNotesService;
    private final IAppLikeSignService appLikeSignService;
    private final IAppLikeNumberService appLikeNumberService;

    /**
     * 查询APP用户关注
     */
    @Override
    public AppFriendVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询APP用户关注列表
     */
    @Override
    public TableDataInfo<AppFriendVo> queryPageList(AppFriendBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<AppFriend> lqw = buildQueryWrapper(bo);
        lqw.orderByDesc(AppFriend::getCreateTime);
        Page<AppFriendVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public AppFriendVo queryUser(Long userId, Long toUserId) {
        LambdaQueryWrapper<AppFriend> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AppFriend::getUserId, userId).eq(AppFriend::getFriendId, toUserId);
        return baseMapper.selectVoOne(wrapper);
    }

    /**
     * 查询APP用户关注列表
     */
    @Override
    public List<AppFriendVo> queryList(AppFriendBo bo) {
        LambdaQueryWrapper<AppFriend> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询APP用户关注列表
     */
    @Override
    public List<AppFriend> list(AppFriendBo bo) {
        LambdaQueryWrapper<AppFriend> lqw = buildQueryWrapper(bo);
        return baseMapper.selectList(lqw);
    }

    /**
     * 查询单个用户关系信息
     *
     * @param userId   用户ID
     * @param friendId 关注的用户
     * @return
     */
    @Override
    public AppFriendVo findByUser(Long userId, Long friendId) {
        LambdaQueryWrapper<AppFriend> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AppFriend::getUserId, userId).eq(AppFriend::getFriendId, friendId);
        return baseMapper.selectVoOne(wrapper);
    }

    @Override
    public String userRelation(Long userId, Long friendId) {
        String isRelation = null;
        if (Objects.isNull(appAddressBookService.queryBook(userId, friendId))) {
            if (Objects.nonNull(findByUser(userId, friendId))) {
                isRelation = Constants.LIKE;
            } else {
                isRelation = Constants.STRANG;
            }
        } else {
            isRelation = Constants.TWO;
        }
        return isRelation;
    }

    private LambdaQueryWrapper<AppFriend> buildQueryWrapper(AppFriendBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<AppFriend> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, AppFriend::getUserId, bo.getUserId());
        lqw.eq(bo.getFriendId() != null, AppFriend::getFriendId, bo.getFriendId());
        lqw.eq(StringUtils.isNotBlank(bo.getTopping()), AppFriend::getTopping, bo.getTopping());
        lqw.eq(bo.getStatus() != null, AppFriend::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getFromStatus()), AppFriend::getFromStatus, bo.getFromStatus());
        lqw.and(bo.getFriendIds()!=null || StringUtils.isNotBlank(bo.getName()), e->e.in(bo.getFriendIds()!=null,AppFriend::getFriendId, bo.getFriendIds())
            .or()
            .like(StringUtils.isNotBlank(bo.getName()),AppFriend::getRemark, bo.getRemark()));
        return lqw;
    }

    /**
     * 新增APP用户关注
     */
    @Override
    public Boolean insertByBo(AppFriendBo bo) {
        AppFriend add = BeanUtil.toBean(bo, AppFriend.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 新增APP用户关注
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insert(AppFriend add) {
        validEntityBeforeSave(add);
        return baseMapper.insert(add) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFriend(AppFriendBo appFriend, String status) {
        //关系不存在，插入用户关系
        if (Objects.isNull(queryUser(appFriend.getUserId(), appFriend.getFriendId()))) {
            insertByBo(appFriend);
        }
    }

    /**
     * 修改APP用户关注
     */
    @Override
    public Boolean updateByBo(AppFriendBo bo) {
        AppFriend update = BeanUtil.toBean(bo, AppFriend.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }


    /**
     * 修改APP用户关注
     */
    @Override
    public Boolean updateByVo(AppFriendVo bo) {
        AppFriend update = BeanUtil.toBean(bo, AppFriend.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }


    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AppFriend entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除APP用户关注
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean delete(Long id) {
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addFridend(Long userId, Long id, String msg) {
        AppFriendVo user = findByUser(userId, id);
        if (Objects.isNull(user)) {
            //添加关注对方信息
            AppFriendBo appFriendBo = new AppFriendBo();
            appFriendBo.setUserId(userId);
            appFriendBo.setFriendId(id);
            appFriendBo.setFromStatus(Constants.SUCCESS);
            insertByBo(appFriendBo);
            AppFriendVo byUser = findByUser(id, userId);
            if (Objects.isNull(byUser)) {
                //如果对方没有关注我，发送好友申请信息,等待对方处理
                update(userId, id, msg);
                AppLikeNumberBo appLikeNumberBo = new AppLikeNumberBo();
                appLikeNumberBo.setUserId(id);
                appLikeNumberBo.setType(TableNumberType.ADD.getCode());
                appLikeNumberService.insertByBo(appLikeNumberBo);
                return false;
            } else {
                //如果对方已经关注了我，说明互相关注，直接成为好友
                //各自添加到对方通讯录
                AppAddressBookVo userBook = appAddressBookService.queryBook(userId, id);
                if (Objects.isNull(userBook)) {
                    AppAddressBook bookUser = new AppAddressBook();
                    bookUser.setUserId(userId);
                    bookUser.setBookId(id);
                    appAddressBookMapper.insert(bookUser);
                }
                AppAddressBookVo friendUserBook = appAddressBookService.queryBook(id, userId);
                if (Objects.isNull(friendUserBook)) {
                    AppAddressBook bookFriend = new AppAddressBook();
                    bookFriend.setUserId(id);
                    bookFriend.setBookId(userId);
                    appAddressBookMapper.insert(bookFriend);
                }
                return true;
            }
        } else {
            //如果添加过关注信息，对方还没关注，更新添加好友信息
            AppFriendVo byUser = findByUser(id, userId);
            if (Objects.isNull(byUser)) {
                //如果对方没有关注我，发送好友申请信息,等待对方处理
                update(userId, id, msg);
            }
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean passFridend(Long userId, Long id, String remark) {
        AppFriendVo byUser = findByUser(userId, id);
        if (Objects.isNull(byUser)) {
            //添加关注对方的记录
            AppFriendBo appFriendBo = new AppFriendBo();
            appFriendBo.setUserId(userId);
            appFriendBo.setFriendId(id);
            appFriendBo.setFromStatus(Constants.SUCCESS);
            insertByBo(appFriendBo);
            //把对方添加到通讯录,并添加备注
            AppAddressBookVo userBook = appAddressBookService.queryBook(userId, id);
            if (Objects.isNull(userBook)) {
                AppAddressBook bookUser = new AppAddressBook();
                bookUser.setUserId(userId);
                bookUser.setBookId(id);
                if (StringUtils.isNotBlank(remark)) {
                    bookUser.setRemark(remark);
                }
                appAddressBookMapper.insert(bookUser);
            }
            //在对方通讯录，添加当前用户
            AppAddressBookVo friendUserBook = appAddressBookService.queryBook(id, userId);
            if (Objects.isNull(friendUserBook)) {
                AppAddressBook bookFriend = new AppAddressBook();
                bookFriend.setUserId(id);
                bookFriend.setBookId(userId);
                appAddressBookMapper.insert(bookFriend);
            }
            return true;
        }
        return false;
    }

    @Override
    public UserVo info(Long userId) {
        UserVo userVo = appUserService.queryByIdUserVo(userId);
        AppFriendBo fans = new AppFriendBo();
        fans.setFriendId(userId);
        fans.setFromStatus(Constants.SUCCESS);
        userVo.setFans(queryList(fans).size());

        AppFriendBo likes = new AppFriendBo();
        likes.setUserId(userId);
        likes.setFromStatus(Constants.SUCCESS);
        userVo.setLikes(queryList(likes).size());

        AppLikeNotesBo appLikeSetting = new AppLikeNotesBo();
        appLikeSetting.setStatus(Constants.SUCCESS);
        appLikeSetting.setUserId(userId);
        List<AppLikeNotesVo> myLikeList = appLikeNotesService.queryList(appLikeSetting);
        userVo.setMyLike(myLikeList.size());

        AppLikeNotesBo appLikeSettingBo = new AppLikeNotesBo();
        appLikeSettingBo.setStatus(Constants.SUCCESS);
        appLikeSettingBo.setSideId(userId);
        List<AppLikeNotesVo> list = appLikeNotesService.queryList(appLikeSettingBo);
        userVo.setLikeMy(list.size());

        userVo.setDynamicVos(appDynamicVideoService.countList(userId, 3L));
        return userVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean canCelLike(AppFriendVo appFriendVo) {
        boolean isFriend = delete(appFriendVo.getId());
        //删除关注的信息
        //如果是好友，删除双方通讯录的好友关系
        AppAddressBookVo nowRelation = appAddressBookService.queryBook(appFriendVo.getUserId(), appFriendVo.getFriendId());
        if (Objects.nonNull(nowRelation)) {
            appAddressBookMapper.deleteById(nowRelation.getId());
        }
        AppAddressBookVo relation = appAddressBookService.queryBook(appFriendVo.getFriendId(), appFriendVo.getUserId());
        if (Objects.nonNull(relation)) {
            appAddressBookMapper.deleteById(relation.getId());
        }
        return isFriend;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean canCelLike(Long userId, Long friendId) {
        boolean isFriend = false;
        AppFriendVo appFriendVo = queryUser(userId, friendId);
        if (Objects.nonNull(appFriendVo)) {
            //删除关注的信息
            delete(appFriendVo.getId());
            //如果是好友，删除双方通讯录的好友关系
            AppAddressBookVo nowRelation = appAddressBookService.queryBook(appFriendVo.getUserId(), appFriendVo.getFriendId());
            if (Objects.nonNull(nowRelation)) {
                appAddressBookMapper.deleteById(nowRelation.getId());
                isFriend = true;
            }
            AppAddressBookVo relation = appAddressBookService.queryBook(appFriendVo.getFriendId(), appFriendVo.getUserId());
            if (Objects.nonNull(relation)) {
                appAddressBookMapper.deleteById(relation.getId());
                isFriend = true;
            }
        }
        return isFriend;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createFriend(Long userId, Long friend) {
        AppFriendVo appFriendVo = queryUser(userId, friend);
        if (Objects.isNull(appFriendVo)) {
            AppFriendBo appFriend = new AppFriendBo();
            appFriend.setFriendId(friend);
            appFriend.setUserId(userId);
            appFriend.setStatus(Constants.SUCCESS);
            appFriend.setFromStatus(Constants.SUCCESS);
            insertByBo(appFriend);
        }
        AppFriendVo friendVo = queryUser(friend, userId);
        if (Objects.isNull(friendVo)) {
            AppFriendBo appFriend = new AppFriendBo();
            appFriend.setFriendId(userId);
            appFriend.setUserId(friend);
            appFriend.setStatus(Constants.SUCCESS);
            appFriend.setFromStatus(Constants.SUCCESS);
            insertByBo(appFriend);
        }
        AppAddressBookVo userBook = appAddressBookService.queryBook(userId, friend);
        if (Objects.isNull(userBook)) {
            AppAddressBook bookUser = new AppAddressBook();
            bookUser.setUserId(userId);
            bookUser.setBookId(friend);
            appAddressBookMapper.insert(bookUser);
        }
        AppAddressBookVo friendUserBook = appAddressBookService.queryBook(friend, userId);
        if (Objects.isNull(friendUserBook)) {
            AppAddressBook bookFriend = new AppAddressBook();
            bookFriend.setUserId(friend);
            bookFriend.setBookId(userId);
            appAddressBookMapper.insert(bookFriend);
        }
    }


    private void update(Long userId, Long id, String msg) {
        String key = CacheConstants.APP_USER_FRIEND + id;
        HashMap<String, Object> info = new HashMap<>(1);
        info.put("msg", msg);
        info.put("time", System.currentTimeMillis());
        RedisUtils.setCacheMapValue(key, userId.toString(), info);
    }
}
